const { Game, Role } = require('board-game');
const extend = require('extend');

const {game: gameConfig} = require('./config');
const Buff = require('./buff');
const Item = require('./item');
const Runner = require('./runner');

class RunningGame extends Game {
    constructor(server, room) {
        super(server, room);

        this.checker = [];
        this.loop();
        this.looper = setInterval(() => this.loop(), gameConfig.tick.item * 1000);
    }

    doAnswer(role, question, answer) {
        let runner = this.board.getRunner(role);
        if (runner.level) {
            console.log('开始答题:', runner.status.index, question, answer);
            if (runner.status.index === question) {
                if (runner.status.answers.length) {
                    if (runner.status.answers[answer].right) {
                        runner.lastWrong = 0;
                        if (runner.hasBuff(Buff.types.violent)) {
                            if (Math.random() * 100 < gameConfig.violent.probability) {
                                this.forward(runner, gameConfig.grid.violent);
                            } else {
                                this.forward(runner, gameConfig.grid.forward);
                            }
                        } else {
                            this.forward(runner, gameConfig.grid.forward);
                        }
                    } else {
                        runner.lastWrong++;
                        this.buff(runner, Buff.types.vertigo, Math.min((runner.lastWrong - 1) * gameConfig.vertigo.growWrong + gameConfig.vertigo.firstWrong, gameConfig.vertigo.maxWrong));
                    }
                }
                runner.nextQuestion();
            }
        }
    }

    loop() {
        this.board.putItem(Item.random(this));
    }

    forward(runner, count = 1) {
        console.log(runner.role.player.name, '准备前进', count, '格');
        let index = this.board.indexOf(runner);
        let prev = index;
        for (let i = 0; i < count; i++) {
            let nextIndex = (index + 1) % this.board.cycle.length;
            if (nextIndex === 0) runner.rounds++;
            let next = this.board.get(nextIndex);
            let last = this.board.count(node => node !== false) <= (gameConfig.grid.space + 1) * 2 || i === 0;
            if (next === true) {
                console.log(runner.role.player.name, '前进了1格', prev, index, nextIndex, last);
                this.board.doNext(prev, nextIndex, runner, last);
            } else if (next === false) {
                console.log(runner.role.player.name, '跳过了一格不存在的格子');
                i--;
                index = nextIndex;
                continue;
            } else if (next instanceof Item) {
                console.log(runner.role.player.name, '获得了道具:', next.type, prev, index, nextIndex, last);
                this.board.doNext(prev, nextIndex, runner, last);
                next.endue(runner);
                return;
            } else if (next instanceof Runner) {
                if (runner.level >= next.level) {
                    console.log(runner.role.player.name, '消灭了', next.role.player.name, prev, index, nextIndex);
                    runner.upgrade(next.level);
                    next.dead();
                    this.buff(runner, Buff.types.violent, gameConfig.violent.kill);
                    this.board.doNext(prev, nextIndex, runner, last);
                    this.willCheckWin(runner)
                } else {
                    console.log(runner.role.player.name, '啃了', next.role.player.name, '一口:' + runner.level);
                    next.downgrade(runner.level);
                    runner.upgrade(runner.level);
                    runner.attack();
                    this.buff(runner, Buff.types.vertigo, gameConfig.vertigo.attack);
                }
                return;
            } else {
                console.log('无效格子', next);
            }
            index = nextIndex;
            prev = index;
        }
    }

    willCheckWin(runner) {
        let timer = setTimeout(() => {
            console.log('检查胜利条件', runner.role.group)
            if (this.checkWin(runner.role.group)) {
                for (let t of this.checker) {
                    clearTimeout(t);
                }
                this.checker = [];
                clearInterval(this.looper);
                runner.win();
            } else {
                let ti = this.checker.indexOf(timer);
                if (ti !== -1) this.checker.splice(ti, 1);
            }
        }, 750);
        this.checker.push(timer);
    }

    buff(runner, type, keep) {
        this.board.buff(runner, type, keep);
    }
    checkBuff(runner, buff) {
        this.board.checkBuff(runner, buff);
    }
    offBuff(runner, buff) {
        this.board.offBuff(runner, buff);
    }

    rebound(runner) {
        this.board.rebound(runner);
    }
}

module.exports = RunningGame;
